package org.ponly.fs.local;

import org.ponly.fs.FileSystem;
import org.ponly.fs.FileSystemException;
import org.ponly.fs.util.IOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

import static org.ponly.fs.FileSystemException.rethrowFileSystemException;

/**
 * 基于本地文件系统的文件系统实现
 *
 * @author tianxuan
 */
public class LocalFileSystem implements FileSystem {
    private static final Logger LOG = LoggerFactory.getLogger(LocalFileSystem.class);
    private static final boolean WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");

    private final String chrootDirectory;  //根目录路径

    /**
     * 创建一个不限制根目录的本地文件系统
     */
    public LocalFileSystem() {
        this(null);
    }

    /**
     * 创建一个限制根目录的本地文件系统
     *
     * @param chrootDirectory 虚拟根目录
     */
    public LocalFileSystem(String chrootDirectory) {
        if (WINDOWS && "/".equals(chrootDirectory)) {
            chrootDirectory = null;
        }
        if (null != chrootDirectory) {
            File chroot = new File(chrootDirectory);
            if (!chroot.isAbsolute()) {
                throw new IllegalArgumentException("chrootDirectory must be is a absolute path");
            }
            if (!chroot.exists() && !chroot.mkdirs()) {
                throw new IllegalArgumentException("chrootDirectory is not exists");
            }
            if (!chroot.isDirectory()) {
                throw new IllegalArgumentException("chrootDirectory must be is a directory");
            }
        }
        this.chrootDirectory = chrootDirectory;
    }



    /**
     * {@inheritDoc}
     */
    @Override
    public InputStream open(String file) throws FileSystemException {
        try {
            File f = this.getFile(file);
            if(!f.exists()){
                LOG.debug("源文件不存在: {}", f);
                return null;
            }
            return new FileInputStream(f);
        } catch (Throwable ex) {
            return rethrowFileSystemException(ex);
        }
    }

    @Override
    public File getFile(String file) {
        return new File(chrootDirectory + file);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void flow(String file,InputStream in, boolean override) throws IOException {
        File f = new File(this.chrootDirectory + file);
        if (!override && f.exists()) {
            throw new FileSystemException("文件已存在: " + file);
        }
        IOUtil.flow(in, new FileOutputStream(f), true, true);
    }
}
